home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / lisp / kcl / akcl / akcl1615.lha / c / sfasl.c < prev    next >
C/C++ Source or Header  |  1992-04-07  |  19KB  |  777 lines

  1.  
  2. /* 
  3. Copyright William Schelter. All rights reserved.
  4. There is a companion file rsym.c which is used to build
  5. a list of the external symbols in a COFF or A.OUT object file, for
  6. example saved_kcl.  These are loaded into kcl, and the
  7. linking is done directly inside kcl.  This saves a good 
  8. deal of time.   For example a tiny file foo.o with one definition
  9. can be loaded in .04 seconds.  This is much faster than
  10. previously possible in kcl.
  11. The function fasload from unixfasl.c is replaced by the fasload
  12. in this file.
  13. this file is included in unixfasl.c
  14. via #include "../c/sfasl.c" 
  15. */
  16.  
  17.  
  18. /* for testing in standalone manner define STAND
  19.  You may then compile this file cc -g -DSTAND -DDEBUG -I../hn
  20.  a.out /tmp/foo.o /public/akcl/unixport/saved_kcl /public/akcl/unixport/
  21.  will write a /tmp/sfasltest file
  22.  which you can use comp to compare with one produced by ld.
  23.  */
  24.  
  25. #define IN_SFASL
  26. #ifdef STAND
  27. #include "config.h"
  28. #include <stdio.h>
  29. #include "mdefs.h"
  30.  
  31. #else
  32. #include "include.h"
  33. #undef S_DATA
  34. #endif
  35.  
  36. #include <varargs.h>
  37. #include "ext_sym.h"
  38. struct node * find_sym();
  39. int node_compare();
  40. char *malloc();
  41. char *the_start;
  42. char *bsearch();
  43.  
  44. struct reloc relocation_info;
  45. /* next 5 static after debug */
  46.  
  47. int debug;
  48.  
  49. #ifdef DEBUG
  50. #define debug sfasldebug
  51. int sfasldebug=0;
  52. #define dprintf(s,ar) if(debug) { printf(" ( s )",ar) ; fflush(stdout);}
  53. #define STAT
  54.  
  55. #else /* end debug */
  56. #define dprintf(s,ar) 
  57. #define STAT static
  58. #endif
  59.  
  60.  
  61. #define MAXPATHLEN 200
  62. #define PTABLE_EXTRA 20
  63.  
  64. STAT struct syment *symbol_table;
  65. STAT char *start_address;
  66. STAT char *my_string_table;
  67. STAT int extra_bss;
  68.  
  69. STAT char command[200];
  70. STAT char tmpfile1 [50]; 
  71.  
  72. #ifndef describe_sym
  73. #define describe_sym(a)
  74. #endif
  75.  
  76. #ifdef STAND
  77. #include "rel_stand.c"
  78. #endif
  79.  
  80.  
  81. #define TEMPSPACE 50000
  82. char tempspace[TEMPSPACE];
  83. char *bil;
  84. char 
  85. *temp_malloc(n)
  86. unsigned int n; 
  87. {char *val;
  88.  val=(char *) (4*((((int)bil)+4)/4));
  89.  bil=val+n;
  90.  if (bil < tempspace +TEMPSPACE)
  91.    return val;
  92.  else {bil=val; 
  93.  dprintf( having to use regular malloc for %d,n);
  94.  return malloc(n);}
  95. }
  96.  
  97. /* begin reloc_file */
  98. #include RELOC_FILE
  99.  
  100. /* end reloc_file */
  101.  
  102. /* free up space which is not allocated in tempspace */
  103.  
  104. #define TEMP_FREE(x) \
  105. if (((char *)x)> tempspace+TEMPSPACE || ((char *)x)< tempspace) \
  106.      free(x)
  107.  
  108. int
  109. fasload(faslfile)
  110. object faslfile;
  111. {       long fasl_vector_start;
  112.     struct filehdr fileheader;
  113. #ifdef COFF
  114.     struct scnhdr sectionheader;
  115.         struct scnhdr section[10];
  116.     struct aouthdr header;
  117. #endif
  118.     int textsize, datasize, bsssize,nsyms;
  119.     int string_size=0;
  120.  
  121.     object memory, data;
  122.     FILE *fp;
  123.     char filename[MAXPATHLEN];
  124.     int i;
  125.     int init_address=0;
  126. #ifndef STAND    
  127.     object *old_vs_base = vs_base;
  128.     object *old_vs_top = vs_top;
  129. #endif
  130.       bil=tempspace; /* reset tmp malloc */
  131.     extra_bss=0;
  132. #ifdef STAND
  133.     strcpy(filename,faslfile);
  134.     fp=fopen(filename,RDONLY);
  135. #else
  136.     coerce_to_filename(faslfile, filename);
  137.     faslfile = open_stream(faslfile, smm_input, Cnil, Kerror);
  138.     vs_push(faslfile);
  139.     fp = faslfile->sm.sm_fp;
  140. #endif    
  141.  
  142.     HEADER_SEEK(fp);
  143.     if(!fread((char *)&fileheader, sizeof(struct filehdr), 1, fp))
  144.       FEerror("Could not get the header",0,0);
  145.     nsyms = NSYMS(fileheader);
  146. #ifdef COFF
  147.  
  148. #ifdef AIX3
  149.     setup_for_aix_load();
  150. #endif    
  151.  
  152.     fread(&header,1,fileheader.f_opthdr,fp);
  153.  
  154.     fread(§ion[1],fileheader.f_nscns,sizeof (struct  scnhdr),fp);
  155.     textsize = section[TEXT_NSCN].s_size;
  156.     datasize = section[DATA_NSCN].s_size; 
  157.     if (strcmp(section[BSS_NSCN].s_name, ".bss") == 0)
  158.       bsssize=section[BSS_NSCN].s_size; 
  159.     else     bsssize=section[BSS_NSCN].s_size = 0;
  160. #endif
  161.  
  162. #ifdef BSD
  163.     textsize=fileheader.a_text;
  164.     datasize=fileheader.a_data;
  165.     bsssize=fileheader.a_bss;
  166. #endif
  167.     symbol_table =
  168.       (struct syment *) temp_malloc(sizeof(struct syment)*
  169.                     (unsigned int)nsyms);
  170.     fseek(fp,(int)( N_SYMOFF(fileheader)),  0);
  171.     {
  172.     for (i = 0;  i < nsyms;  i++)
  173.         {fread((char *)&symbol_table[i], SYMESZ, 1, fp);
  174.          dprintf( symbol table %d , i);
  175.          if (debug) describe_sym(i);
  176.          dprintf( at %d , &symbol_table[i]);
  177. #ifdef HPUX
  178.          symbol_table[i].n_un.n_strx = string_size;
  179.          dprintf(string_size %d, string_size);
  180.          string_size += symbol_table[i].n_length + 1;
  181.          fseek(fp,(int)symbol_table[i].n_length,1);
  182. #endif
  183.            }
  184.        }
  185. /*    
  186. on MP386
  187. The sizeof(struct syment) = 20, while only SYMESZ =18. So we had to read
  188. one at a time.
  189. fread((char *)symbol_table, SYMESZ*fileheader.f_nsyms,1,fp);
  190. */
  191.  
  192. #ifdef READ_IN_STRING_TABLE
  193.  
  194. my_string_table=READ_IN_STRING_TABLE(fp,string_size);
  195.  
  196. #else  
  197. #ifdef MUST_SEEK_TO_STROFF
  198.   fseek(fp,N_STROFF(fileheader),0);
  199. #endif    
  200.   {int ii=0;
  201.     if (!fread((char *)&ii,sizeof(int),1,fp))
  202.           {FEerror("The string table of this file did not have any length",0,
  203.            0);}
  204.         fseek(fp,-4,1);
  205.         /* at present the string table is located just after the symbols */
  206.         my_string_table=temp_malloc((unsigned int)ii);
  207.         dprintf( string table leng = %d, ii);
  208.  
  209.         if(ii!=fread(my_string_table,1,ii,fp))
  210.           FEerror("Could not read whole string table",0,0) ;
  211.     }
  212. #endif    
  213. #ifdef SEEK_TO_END_OFILE
  214. SEEK_TO_END_OFILE(fp);    
  215. #else    
  216.      while ((i = getc(fp)) == 0)
  217.         ;
  218.     ungetc(i, fp);
  219. #endif
  220.     
  221.     fasl_vector_start=ftell(fp);
  222.  
  223.    if (!((c_table.ptable) && *(c_table.ptable)))
  224.      build_symbol_table();
  225.  
  226. /* figure out if there is more bss space needed */
  227.     extra_bss=get_extra_bss(symbol_table,nsyms,datasize+textsize+bsssize,
  228.                 &init_address,bsssize);
  229.     
  230. /* allocate some memory */
  231. #ifndef STAND    
  232.     memory = alloc_object(t_cfdata);
  233.     memory->cfd.cfd_self = 0;
  234.     memory->cfd.cfd_start = 0;
  235.     memory->cfd.cfd_size = datasize+textsize+bsssize + extra_bss;
  236.     vs_push(memory);
  237.         the_start=start_address=        
  238.      memory->cfd.cfd_start =    
  239.      alloc_contblock(memory->cfd.cfd_size);
  240.  
  241. #else
  242.     the_start=start_address
  243.       = malloc(datasize+textsize+bsssize + extra_bss + 0x80000);
  244.     the_start=start_address= (char *)(
  245.        0x1000* ((((int)the_start + 0x70000) + 0x1000)/0x1000));
  246.     
  247. #endif
  248.  
  249.     dprintf( code size %d , datasize+textsize+bsssize + extra_bss);
  250.     if (fseek(fp,N_TXTOFF(fileheader) ,0) < 0)
  251.         FEerror("file seek error",0,0);
  252.     fread(the_start, textsize + datasize, 1, fp);
  253.     dprintf(read into memory text +data %d bytes, textsize + datasize);
  254. /* relocate the actual loaded text  */
  255.  
  256.         dprintf( the_start %x, the_start);
  257.  
  258.     /* record which symbols are used */
  259.   
  260. #ifdef SYM_USED
  261.   {int j=0;
  262.      for(j=1; j< BSS_NSCN ; j++)
  263.        { dprintf( relocating section %d \n,j);
  264.     if (section[j].s_nreloc) fseek(fp,section[j].s_relptr,0);
  265.         for(i=0; i < section[j].s_nreloc; i++)
  266.       { struct syment *sym;
  267.         fread(&relocation_info, RELSZ, 1, fp);
  268.         sym = & symbol_table[relocation_info.r_symndx];
  269.         if (TC_SYMBOL_P(sym))
  270.           SYM_USED(sym) = 1;
  271.         }}}
  272. #endif
  273.  
  274.  
  275.     /* this looks up symbols in c.ptable and also adds new externals to
  276.        that c.table */
  277.     relocate_symbols(NSYMS(fileheader));  
  278.     
  279. #ifdef COFF
  280.   {int j=0;
  281.      for(j=1; j< BSS_NSCN ; j++)
  282.        { dprintf( relocating section %d \n,j);
  283.     if (section[j].s_nreloc) fseek(fp,section[j].s_relptr,0);
  284.         for(i=0; i < section[j].s_nreloc; i++)
  285.       /* RELSZ = sizeof(relocation_info) */
  286.       {fread(&relocation_info, RELSZ, 1, fp);
  287.            dprintf(relocating %d,i);
  288.        relocate();};
  289.         }};
  290. #endif
  291. #ifdef BSD
  292.      fseek(fp,N_RELOFF(fileheader),0);
  293.     {int nrel = (fileheader.a_trsize/sizeof(struct reloc));
  294.      for (i=0; i < nrel; i++)
  295.        {fread((char *)&relocation_info, sizeof(struct reloc),
  296.             1, fp);
  297.           dprintf(relocating %d,i);
  298.           relocate();
  299.         }
  300.     }
  301. #ifdef N_DRELOFF
  302.      fseek (fp, N_DRELOFF(fileheader), 0);
  303. #endif
  304.      {int nrel = (fileheader.a_drsize/sizeof(struct reloc));
  305.       the_start += fileheader.a_text;
  306.      for (i=0; i < nrel; i++)
  307.  
  308.        {fread((char *)&relocation_info, sizeof(struct reloc),
  309.             1, fp);
  310.           dprintf(relocating %d,i);
  311.           relocate();
  312.         }
  313.        }
  314. #endif
  315.  
  316. /* end of relocation */
  317.        dprintf( END OF RELOCATION \n,0);
  318.        dprintf( invoking init function at %x, start_address)
  319.        dprintf( textsize is %x,textsize);
  320.        dprintf( datasize is %x,datasize);
  321.  
  322. /* read in the fasl vector */
  323.     fseek(fp,fasl_vector_start,0);
  324.         if (feof(fp))
  325.       {data=0;}
  326.          else{
  327.     data = read_fasl_vector(faslfile);
  328.     vs_push(data);
  329. #ifdef COFF
  330.        dprintf( read fasl now symbols %d , fileheader.f_nsyms);
  331. #endif
  332.     }
  333.     close_stream(faslfile, 1);    
  334.  
  335. /*
  336.  {
  337.     int fd;
  338.  
  339.     fd = creat ("xsakcl.bits", 0777);
  340.     write (fd, memory->cfd.cfd_start, textsize + datasize);
  341.     close (fd);
  342.  
  343.     fd = open ("xsl2.bits", 0);
  344.     read (fd, memory->cfd.cfd_start, memory->cfd.cfd_size);
  345.     close (fd);
  346.  }
  347. */
  348.  
  349. #ifndef STAND
  350.     TEMP_FREE(my_string_table);
  351.     TEMP_FREE(symbol_table);
  352.  
  353.  
  354. #ifdef CLEAR_CACHE
  355.     CLEAR_CACHE;
  356. #endif
  357.     call_init(init_address,memory,data);
  358.     
  359.         vs_base = old_vs_base;
  360.     vs_top = old_vs_top;
  361.        if(symbol_value(Vload_verbose)!=Cnil)
  362.         printf("start address -T %x ",memory->cfd.cfd_start);
  363.     return(memory->cfd.cfd_size);
  364. #endif
  365.     {FILE *out;
  366.      out=fopen("/tmp/sfasltest","w");
  367.      fwrite((char *)&fileheader, sizeof(struct filehdr), 1, out);
  368.      fwrite(start_address,sizeof(char),datasize+textsize,out);
  369.      fclose(out);}
  370.      printf("\n(start %x)\n",start_address);
  371.  
  372. }
  373.  
  374. #ifdef AIX3
  375. struct syment *
  376. get_symbol(name,scnum,symbol_table,length)
  377.      char *name;
  378.      int scnum,length;
  379.      struct syment *symbol_table;
  380. { struct syment *end,*sym;
  381.  char tem[SYMNMLEN +1];
  382.   char *na;
  383.   end =symbol_table + length;
  384.   for(sym=symbol_table; sym < end; sym += (NUM_AUX(sym) +1))
  385.     {if ((sym)->n_scnum  == scnum)
  386.       { na=SYM_NAME(sym);
  387.     if (strcmp(name,na) == 0)
  388.       {return sym;}}}
  389.   return 0;}
  390. #endif /* aix3 */
  391.  
  392. struct node *
  393. find_sym(sym,name)
  394.   struct syment *sym;
  395.    char *name;
  396. { char tem[SYMNMLEN +1];
  397.   tem [SYMNMLEN] = 0;
  398.   if (name==0) name = SYM_NAME(sym);
  399.   {struct node joe,*answ;
  400.    joe.string=name;
  401.    answ =  (struct node *)  bsearch((char *)(&joe),(char*) (c_table.ptable),
  402.              c_table.length,
  403.              sizeof(struct node), node_compare);
  404.  
  405.    return answ;
  406.  }}
  407.        
  408.            
  409. get_extra_bss(symbol_table,length,start,ptr,bsssize)
  410. int length,bsssize;
  411. struct syment *symbol_table;
  412. int *ptr;   /* store init address offset here */
  413. {int result = start;
  414.  int next_bss =  start - bsssize;
  415.  struct syment *end,*sym;
  416.  char tem[SYMNMLEN +1];
  417.  end =symbol_table + length;
  418.  for(sym=symbol_table; sym < end; sym++)
  419.    {
  420.      
  421. #ifdef FIND_INIT
  422. FIND_INIT
  423. #endif
  424.  
  425. #ifdef AIX3
  426.  /* we later go through the relocation entries making this 1
  427.     for symbols used */
  428. #ifdef SYM_USED 
  429.  if(TC_SYMBOL_P(sym))
  430.    {SYM_USED(sym) = 0;}
  431. #endif
  432.  
  433.  /* fix up the external refer to _ptrgl to be local ref */
  434.  if (sym->n_scnum == 0 &&
  435.      strcmp(sym->n_name,"_ptrgl")==0)
  436.    {struct syment* s =
  437.       get_symbol("._ptrgl",TEXT_NSCN,symbol_table,length);
  438.     if (s ==0) FEerror("bad glue",0);
  439.     sym->n_value = next_bss ;
  440.     ptrgl_offset = next_bss;
  441.     ptrgl_text = s->n_value;
  442.     next_bss += 0xc;
  443.     sym->n_scnum = DATA_NSCN;
  444.     ((union auxent *)(sym+1))->x_csect.x_scnlen = 0xc;
  445.  
  446.   }
  447.  
  448.      if(sym->n_scnum != BSS_NSCN) goto NEXT;
  449.      if(SYM_EXTERNAL_P(sym))
  450.        {int val=sym->n_value;
  451.     struct node joe;
  452.     if (val && c_table.ptable)
  453.       {struct node *answ;
  454.        answ= find_sym(sym,0);
  455.            if(answ)
  456.          {sym->n_value = answ->address ;
  457.           sym->n_scnum = N_UNDEF;
  458.           val= ((union auxent *)(sym+1))->x_csect.x_scnlen;
  459.           result -= val;
  460.           goto NEXT;
  461.         }}
  462.       }
  463.  /* reallocate the bss space */
  464.  if (sym->n_value == 0)
  465.    {result += ((union auxent *)(sym+1))->x_csect.x_scnlen;}
  466.  sym->n_value = next_bss;
  467.  next_bss += ((union auxent *)(sym+1))->x_csect.x_scnlen;
  468.  NEXT:
  469.  ;
  470.      /* end aix3 */
  471. #endif
  472.       
  473.  
  474.   
  475. #ifdef BSD
  476.      tem; /* ignored */
  477.      if(SYM_EXTERNAL_P(sym) && SYM_UNDEF_P(sym))
  478. #endif
  479. #ifdef COFF
  480.      if(0)
  481.      /* what we really want is
  482.     if (sym->n_scnum==0 && sym->n_sclass == C_EXT
  483.                         && !(bsearch(..in ptable for this symbol)))
  484.     Since this won't allow loading in of a new external array
  485.     char foo[10]  not ok
  486.     static foo[10] ok.
  487.     for the moment we give undefined symbol warning..
  488.     Should really go through the symbols, recording the external addr
  489.     for ones found in ptable, and for the ones not in ptable
  490.     set some flag, and add up the extra_bss required.  Then
  491.     when you have the new memory chunk in hand,
  492.     you could make the pass setting the relative addresses.
  493.     for the ones you flagged last time.
  494.     */
  495. #endif
  496.        /* external bss so not included in size of bss for file */
  497.        {int val=sym->n_value;
  498.     if (val && c_table.ptable
  499.         && (0== find_sym(sym,0)))
  500.        { sym->n_value=result;
  501.          result += val;}}
  502.      
  503.      sym += NUM_AUX(sym); 
  504.  
  505.    }
  506.  return (result-start);
  507. }
  508.  
  509.  
  510.  
  511. /* go through the symbol table changing the addresses of the symbols
  512. to reflect the current cfd_start */
  513.  
  514.  
  515.  
  516. relocate_symbols(length)
  517. unsigned int length;
  518. {struct syment *end,*sym;
  519.  unsigned int typ;
  520.  char *str;
  521.  char tem[SYMNMLEN +1];
  522.  tem[SYMNMLEN]=0;
  523.  end =symbol_table + length;
  524.  for(sym=symbol_table; sym < end; sym++) {
  525.     typ=NTYPE(sym);
  526. #ifdef BSD
  527. #ifdef N_STAB    
  528.     if (N_STAB & sym->n_type) continue;/* skip: It  is for dbx only */
  529. #endif    
  530.     typ=N_SECTION(sym);
  531. /* if(sym->n_type  &  N_EXT) should add the symbol name,
  532.    so it would be accessible by future loads  */
  533. #endif
  534.    switch (typ)    {
  535. #ifdef BSD
  536.    case N_ABS : case N_TEXT: case N_DATA: case N_BSS:
  537. #endif
  538. #ifdef COFF
  539.    case TEXT_NSCN : case DATA_NSCN: case BSS_NSCN :
  540. #endif
  541.      str=SYM_NAME(sym);
  542.      dprintf( for sym %s ,str)
  543.      dprintf( new value will be start %x, start_address);
  544.  
  545. #ifdef AIX3 
  546.      if(N_SECTION(sym) == DATA_NSCN
  547.     && NUM_AUX(sym) 
  548.     && allocate_toc(sym))
  549.        break;
  550. #endif     
  551.        sym->n_value = (int)start_address;
  552.      break;
  553.    case  N_UNDEF:
  554.      str=SYM_NAME(sym);
  555.      dprintf( undef symbol %s ,str);    
  556.      dprintf( symbol diff %d , sym - symbol_table);
  557.      describe_sym(sym-symbol_table);
  558.      set_symbol_address(sym,str);
  559.      describe_sym(sym-symbol_table);
  560.      break;
  561.    default:
  562. #ifdef COFF
  563.      dprintf(am ignoring a scnum %d,(sym->n_scnum));
  564. #endif
  565.      break;
  566.    }
  567.    sym += NUM_AUX(sym);
  568.  }
  569. }
  570.  
  571. /* 
  572. STEPS:
  573. 1) read in the symbol table from the file,
  574. 2) go through the symbol table, relocating external entries.
  575. 3) for i <=2 go thru the relocation information for this section
  576.  relocating the text.
  577. 4) done.
  578. */
  579.  
  580. set_symbol_address(sym,string)
  581. struct syment *sym;
  582. char *string;
  583. {struct node *answ;
  584.  if (c_table.ptable)
  585.     {
  586.      dprintf(string %s, string);
  587.     answ = find_sym(sym,string);
  588.      dprintf(answ %d , (answ ? answ->address : -1));
  589.     if(answ)
  590.      {
  591. #ifdef COFF
  592. #ifdef _AIX370
  593.      if (NTYPE(sym) == N_UNDEF)   
  594.        sym->n_value = answ->address;
  595.      else 
  596. #endif 
  597.       sym->n_value = answ->address -sym->n_value;
  598.       /* for symbols in the local  data,text and bss this gets added
  599.      on when we add the current value */
  600. #endif
  601. #ifdef BSD
  602.       /* the old value of sym->n_value is the length of the common area
  603.      starting at this address */
  604.       sym->n_value = answ->address;
  605. #endif
  606. #ifdef AIX3
  607.      fix_undef_toc_address(answ,sym,string);
  608. #endif
  609.       
  610. }      
  611.      else
  612.       {
  613.  
  614. #ifdef BSD
  615.     {char *name;
  616.      name=malloc(1+strlen(string));
  617.      strcpy(name,string);
  618.      sym->n_value = sym->n_value + (unsigned int) the_start;
  619.      add_symbol(name,sym->n_value,NULL);
  620.        }
  621. #endif
  622.  
  623.      fprintf(stdout,"undefined %s symbol",string)
  624.       ;fflush(stdout);
  625.      
  626.    }}
  627.  
  628.     else{FEerror("symbol table not loaded",0,0);}}
  629.  
  630. /*
  631. #define ADD_SYMBOL(name) add_symbol("name",(int) &(name),0)
  632. Use the add_symbol to add a c symbol, which you want to refer
  633. to in subsequent loads.  The address used in subsequent loads,
  634. will be the load address of the current symbol.
  635. Such a symbol may only be added once, since subsequent references
  636. will try to link to the old address.
  637. */
  638.  
  639. build_symbol_table()
  640. {  printf("Building symbol table for %s ..\n",kcl_self);fflush(stdout);
  641.    sprintf(tmpfile1,"rsym%d",getpid());
  642.    coerce_to_filename(symbol_value(siVsystem_directory),
  643.               system_directory);
  644. #ifndef RSYM_COMMAND
  645.    sprintf(command,"%srsym %s %s",system_directory,kcl_self,tmpfile1);
  646. #else
  647.    RSYM_COMMAND(command,system_directory,kcl_self,tmpfile1);
  648. #endif   
  649.    if (system(command) != 0)
  650.      FEerror("The rsym command ~a failed .",1,make_simple_string(command)
  651.          );
  652.  
  653.    read_special_symbols(tmpfile1);
  654.    unlink(tmpfile1);
  655.    dprintf(c_table %d , c_table.length);
  656.    qsort((char*)(c_table.ptable),(int)(c_table.length),sizeof(struct node),node_compare);
  657.  }
  658.  
  659.  
  660.  
  661. /*to do:Addition of one symbol to the ptable is very slow, because we 
  662. sort each time! */
  663.  
  664. add_symbol(va_alist)
  665.      va_dcl
  666. {char *string;
  667.  int address;
  668.  int nstr,i;
  669.  va_list ap;
  670.  
  671.   /* terminate arg list with NULL pointer */
  672.  
  673.  if(!(c_table.ptable)) return ; /* this is in a function before ptable is init */
  674.  nstr=0;
  675.  /* count the number of strings */
  676.  
  677.  va_start(ap);
  678.  while (va_arg(ap,char*)!=0) 
  679.    { nstr++;
  680.      va_arg(ap,int);
  681.      if (nstr >1000) FEerror("Did you really give 1000 strings or just forget 0 ending",0,0);};
  682.  va_end(ap);
  683.  
  684.  va_start(ap);
  685.  if (( int)((c_table.alloc_length) - (c_table.length)) -nstr>0)
  686.    { 
  687.    BEGIN:
  688.      for(i=0;i<2*nstr;i=i+2)
  689.        { string=va_arg(ap,char *);
  690.      if(find_sym(0,string))
  691.        {FEerror("The string ~a is already in the ptable",1,
  692.             make_simple_string(string));};
  693.      {struct node *u;
  694.       u= ((*(c_table.ptable))+((c_table.length)+(i/2)));
  695.       u->string = string;
  696.       u->address = va_arg(ap,int);}
  697.        }
  698.      (c_table.length)=(c_table.length)+nstr;
  699.      qsort((char*)(c_table.ptable),(int)(c_table.length),sizeof(struct node),node_compare);
  700.    }
  701.  else 
  702.    /* grow the ptable */
  703.    { TABL *new, *old_pt;
  704.      new=
  705.       (TABL *)malloc(sizeof(struct node)
  706.          *((c_table.alloc_length)=((c_table.length) + nstr + PTABLE_EXTRA)));
  707.      old_pt=(c_table.ptable);
  708.      /* copy it */
  709.      {register int i ;
  710.       for (i=0; i < c_table.length; i++)
  711.     {(*new)[i].string=(*old_pt)[i].string;
  712.      (*new)[i].address=(*old_pt)[i].address;}}
  713.      
  714.      (c_table.ptable)=new; 
  715.      free((char *)old_pt);
  716.      goto BEGIN ;
  717.    }
  718.  va_end(ap);
  719.  
  720.  
  721.  /* this is in fat_string.c for the moment */
  722. /*
  723. read_special_symbols(symfile)
  724. char *symfile;
  725. {FILE *symin;
  726.  char *symbols;
  727.  int i,jj;
  728.  struct lsymbol_table tab;
  729.  if (!(symin=fopen(symfile,"r")))
  730.    {perror(symfile);exit(1);};
  731.  fread((char *)&tab,sizeof(tab),1,symin);
  732.  symbols=malloc(tab.tot_leng);
  733.  c_table.alloc_length=( (PTABLE_EXTRA+ tab.n_symbols));
  734.  c_table.ptable =(TABL *)malloc(sizeof(struct node) * (c_table.alloc_length));
  735.  if (!(c_table.ptable)) {perror("could not allocate"); exit(1);};
  736.  i=0;
  737.  c_table.length = tab.n_symbols;
  738.  while(i < tab.n_symbols)
  739.    { fread((char *)&jj,sizeof(int),1,symin);
  740.      (SYM_ADDRESS(c_table,i))=jj;
  741.      SYM_STRING(c_table,i)=symbols;
  742.  
  743.      while( *(symbols++) =   getc(symin)) 
  744.        {;}
  745.      dprintf( name %s ,  SYM_STRING(c_table,i));
  746.      dprintf( address %d , jj);
  747.      i++;
  748.    }
  749.  
  750. }
  751.  
  752. */
  753.  
  754. #ifdef DEBUG
  755. print_name(p)
  756.      struct syment *p;
  757. {char tem[10],*name;
  758.  name=SYM_NAME(p);
  759.  name=   (((p)->_n._n_n._n_zeroes == 0) ? 
  760.         &my_string_table[(p)->_n._n_n._n_offset] :
  761.                ((p)->_n._n_name[SYMNMLEN -1] ? 
  762.                  (strncpy(tem,(p)->_n._n_name,  
  763.                        SYMNMLEN), 
  764.                   (char *)tem) : 
  765.                   (p)->_n._n_name ));
  766.  
  767.  printf("(name:|%s|)",name);
  768.  printf("(sclass 0x%x)",p->n_sclass);
  769.   printf("(external_p 0x%x)",SYM_EXTERNAL_P(p));
  770.  printf("(n_type 0x%x)",p->n_type);
  771.  printf("(n_value 0x%x)",p->n_value);
  772.  printf("(numaux 0x%x)\n",NUM_AUX(p));
  773.  fflush(stdout);
  774. }
  775. #endif
  776.